﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Input;
using Structures;

namespace X3DXamlXna
{
    public interface ISpaceSubdivisionComponent
    {
        List<X3dModel> models { get; set; }
        void start();
    }
    class SpaceSubdivisionComponent : GameComponent, ISpaceSubdivisionComponent
    {
        public List<X3dModel> models { get; set; }
        private bool go = false;

        private KDObjects _root;
        public KDObjects root { get { return _root; } private set { _root = value; } }

        public SpaceSubdivisionComponent(Game game)
            : base(game)
        {
            game.Services.AddService(typeof(ISpaceSubdivisionComponent), this);
        }
        public override void Initialize()
        {
            models = new List<X3dModel>();
            base.Initialize();
        }
        public override void Update(GameTime gameTime)
        {
            if (go)
            {
                var camera = Game.Services.GetService(typeof(ICameraService)) as ICameraService;
                var drawableService = Game.Services.GetService(typeof(IDrawableModel)) as IDrawableModel;
                //Load(root, camera);
                List<X3dModel> maybeModelsToDraw = Utils.intersectModels(camera.CurrentCamera.BoundingFrustum, root, Game.GraphicsDevice);
                //creao una lista nuova di elementi da disegnare in maniera tale che i vecchi modelli non  
                //si mischino i con i nuovi da disegnare
                //drawableService.models = models.Distinct() as List<X3dModel>;
                if (drawableService.ready)
                {
                    drawableService.models = maybeModelsToDraw;
                }
            }
            base.Update(gameTime);
        }
        public void start()
        {            
            //ora costruisco il mio kdtree dove nelle foglie avro' i riferimenti ai modelli da caricare
            root = new KDNode(models);
            go = true;
        }
//#warning solo caricamento e comunque orribilemente inefficiente!!!! ora vado a Letto. A domani
//        void Load(KDObjects root, ICameraService camera)
//        {
//            if (root == null || root.Models.Count != 0 || !root._Box.Intersects(camera.myBoundingFrustum)) return;
//            root.LoadContent(Game.GraphicsDevice);
//            if (root.left != null)
//            {
//                Load(root.left, camera);
//            }
//            if (root.right != null)
//            {
//                Load(root.right, camera);
//            }

//        }
        
    }
    public class Vec3Model
    {
        private X3dModel _model;
        public X3dModel Model { get { return _model; } private set { _model = value; } }

        private Vector3 _coord;
        public Vector3 Coord { get { return _coord; } private set { _coord = value; } }

        public Vec3Model(Vector3 vec, X3dModel mod)
        {
            Coord = vec;
            Model = mod;
        }
    }
}
